﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data.Common;
using System.Diagnostics;
using System.Linq.Expressions;
using System.Reflection;
using System.Security.Claims;
using System.Threading.Tasks;
using AntDesign.TableModels;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.Rendering;
using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage;
using Microsoft.AspNetCore.Components.Web;
using NewLife.Data;
using NewLife.Net;
using Org.BouncyCastle.Ocsp;
using SageKing.Blazor.OpenIdService.Components.Application.Pages.Manage.Components;
using SageKing.Database.EF.Entity.Contracts;
using static System.Runtime.InteropServices.JavaScript.JSType;
using static MudBlazor.Components.Chart.Models.TimeSeriesChartSeries;
using Icon = AntDesign.Icon;

namespace SageKing.Blazor.OpenIdService.Components.Base;

public abstract class AuthComponentTabTableBase<T, K> : AuthComponentTabBase
      where T : IEntityBaseId<K>, new()
{

    #region 参数
    /// <summary>
    /// 当前类型
    /// </summary>
    public virtual AuthComponentTabTableBase<T, K> Me { get; set; }

    [Parameter]
    public virtual string tableHeightCssName { get; set; } = "tableHeightCssName";

    [Parameter]
    public virtual double tableHeight { get; set; } = 600;

    [Parameter]
    public virtual string tableScrollX { get; set; } = "600";

    [Parameter]
    public virtual EventCallback<RowData<T>> OnRowClickEvent { get; set; }


    public IModal<T> modal { get; set; }

    #region table 动态列表
    /// <summary>
    /// 当前实体属性
    /// </summary>
    public virtual Dictionary<string, (string Name, Type PropertyType, PropertyInfo PropertyInfo, bool isJsonColumn)> ModelPropertyTypeDic { get; set; } = typeof(T).GetProperties().ToDictionary(a => a.Name, a => (a.Name, a.PropertyType, a, false));
    public virtual IEnumerable<string> ColumnsByNamesHide => ModelPropertyTypeDic.Keys.Where(a => !ColumnsByNamesShow.Contains(a)).ToArray();

    public virtual List<string> ColumnsByNamesShow { get; set; } = ["DisplayName", "Type", "Status", "OrderNo", "Remark", "CreateUserName"];
    /// <summary>
    /// 不需要处理CellRender的列
    /// </summary>
    public virtual IEnumerable<string> ColumnsByNamesNotCellRender { get; set; } = new[] { "SortNo", "OrderNo", "CreateUserName" };
    /// <summary>
    /// 列属性配置
    /// </summary>
    public virtual Dictionary<string, Dictionary<string, object>> ColumnsByNamesPropertySet { get; set; } = new Dictionary<string, Dictionary<string, object>>()
    {
        //{ "Status",new Dictionary<string, object>()
        //    { { "Disabled",true } } },
        //{ "Enable",new Dictionary<string, object>()
        //    { { "Disabled",true } } },
        { "type",new Dictionary<string, object>()
            { { "Disabled",true } } },
    };
    /// <summary>
    /// 显示标题
    /// </summary>
    public virtual Dictionary<string, string> ColumnsTitleDic { get; set; } = new() {
        { "DisplayName", "显示名称" },
        { "Type", "类型" },
        { "Status", "状态" },
        { "OrderNo", "排序" },
        { "Remark", "备注" },
        { "CreateUserName", "时间相关" },
    };

    #endregion


    #region Page参数
    [Parameter]
    public int PageSize { get; set; } = 10;
    [Parameter]
    public int[] PageSizeOptions { get; set; } = [10, 20, 50, 100, 500, 1000];
    #endregion
    #endregion

    #region Table 相关

    //table
    public Table<T> table { get; set; }
    public bool tableLoading { get; set; }
    public bool isOnRowExpand { get; set; } = false;

    public IEnumerable<T> selectedRows { get; set; } = new List<T>();
    public string selectedCol { get; set; }
    public T selectedRow { get; set; }
    public bool Editing { get; set; } = false;
    public bool IsSelectMulti { get; set; } = false;
    public RowData<T> selectedRowData { get; set; }
    public PageBase<T> pageData { get; set; }
    public virtual SelectionType selectionType { get; set; } = SelectionType.Checkbox;

    public virtual PaginationEventArgs pageargs { get; set; } = new PaginationEventArgs(1, 10);

    //search
    public virtual T searchModel { get; set; }
    #endregion

    #region Inject 相关

    /// <summary>
    /// 需要重写注入
    /// </summary>
    public virtual IBaseService<T, K> DataService { get; }
    #endregion

    #region Init
    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();
        await InitSelectData();
        await InitSeachMain();
    }
    public virtual async Task InitSelectData()
    {
        selectedRows = new List<T>();
        await Task.CompletedTask;
    }

    public virtual async Task InitSeachMain()
    {
        searchModel = new();
        await Task.CompletedTask;
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        await base.OnAfterRenderAsync(firstRender);

        if (firstRender)
        {
            UpdateHeightAction();
            StateHasChanged();
        }
    }


    #endregion

    #region Even Handle
    public virtual async Task OnRowClickEventHandlerAsync(RowData<T> e)
    {
        if (OnRowClickEvent.HasDelegate)
        {
            await OnRowClickEvent.InvokeAsync(e);
        }
        await Task.CompletedTask;
    }
    #endregion

    #region 用于处理Action回调

    public virtual void OnModelChangedAction(T model, ChangedEnum changedEnum)
    {

        var tmpList = pageData.Items.ToList();
        var tmpOld = tmpList.FirstOrDefault(a => a.Id.Equals(model.Id));
        int getindex = tmpOld == null ? -1 : tmpList.IndexOf(tmpOld);

        switch (changedEnum)
        {
            case ChangedEnum.Added:
                tmpList.Add(model);
                break;
            case ChangedEnum.Modified:
                if (getindex < 0)
                {
                    return;
                }
                tmpList[getindex] = model;
                break;
            case ChangedEnum.Deleted:
                tmpList.RemoveAt(getindex);
                break;
            default:
                break;
        }
        ;
        pageData.Items = tmpList;
    }
    #endregion

    #region 通用方法
    public virtual void ReSet()
    {
        searchModel = new();
    }

    public virtual async Task Refresh(bool notice = true)
    {
        // 异步等待获取锁。如果锁已被占用，此处不会阻塞线程，而是返回一个Task等待
        await _asyncLock.WaitAsync().ConfigureAwait(false);
        try
        {
            await OnSearch(pageargs);
            if (isOnRowExpand)
            {
                table?.CollapseAll();
                isOnRowExpand = false;
            }
            if (notice)
            {
                _ = Message.SuccessAsync("刷新成功!");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
        }
        finally
        {
            _asyncLock.Release();
        }
    }
    public virtual async void OnRowExpand(RowData<T> data)
    {
        await Task.CompletedTask;
    }
    public virtual async void OnRowClick(RowData<T> data)
    {
        Stopwatch stopwatch = Stopwatch.StartNew();

        CheckSelectedRowEditing(data);

        await OnRowClickEventHandlerAsync(data);
        stopwatch.Stop();

        if (stopwatch.ElapsedMilliseconds > 300)
        {
            Console.WriteLine($"OnRowClick: Time:{stopwatch.ElapsedMilliseconds} ms");
        }
    }

    public virtual void CheckSelectedRowEditing(RowData<T> data)
    {
        if (Editing)
        {
            //还原上次
            if (selectedRowData != null)
            {
                selectedRowData.Editing = false;
            }
            data.Editing = true;
        }
        selectedRowData = data;
        selectedRow = data.Data;

        if (IsSelectMulti)
        {
            if (!selectedRows.Where(a => a.Id.Equals(selectedRow.Id)).Any())
            {
                var old = selectedRows.ToList();
                old.Add(selectedRow);
                selectedRows = old;
            }
        }
        else
        {
            selectedRows = new List<T>() { selectedRow };
        }
    }

    public virtual void ShowMessage(string msg = "查询成功")
    {
        _ = Message.SuccessAsync(msg);
    }

    public virtual void OnChangeTable(QueryModel<T> query)
    {
        Console.WriteLine(query.toJsonStr());

        //pageData.Items = query.ExecuteQuery(pageData.Items.AsQueryable())
        //    .Where(x => string.IsNullOrWhiteSpace(searchString) || x.Name.Contains(searchString, StringComparison.OrdinalIgnoreCase));
    }
    #endregion

    #region 需要重写
    #region OnSearch
    /// <summary>
    /// 用于搜索条件
    /// </summary>
    public virtual List<(bool, Expression<Func<T, bool>>)> SearchWhereIf { get; set; }

    public virtual Expression<Func<T, object>> Orderby { get; set; }
    /// <summary>
    /// 需要重写
    /// </summary>
    /// <param name="args"></param>
    /// <returns></returns>
    public virtual async Task OnSearch(PaginationEventArgs args)
    {
        tableLoading = true;

        pageargs.Page = args.Page;
        pageargs.PageSize = args.PageSize;

        var page = new PageBaseInput() { Page = pageargs.Page, PageSize = pageargs.PageSize };
        //todo : 这里可以添加查询逻辑 

        var getData = await DataService.GetPage(page, SearchWhereIf,
            Orderby, false);

        CheckPageData(getData);

        pageData = getData;

        tableLoading = false;
        await Task.CompletedTask;
    }

    /// <summary>
    /// 处理查询后的数据及检测,如检测 扩展列
    /// </summary>
    /// <param name="pageData"></param>
    public virtual void CheckPageData(PageBase<T> pageData)
    {

    }
    #endregion
    #endregion

    #region 动态列表

    /// <summary>
    /// 动态列表 默认实现
    /// </summary>
    /// <param name="propertyName"></param>
    /// <param name="column"></param>
    /// <returns></returns>
    public virtual (Type valuetype, Type columnType, object colObj) DefinitionColumnsBase(string propertyName, IFieldColumn column)
    {
        Stopwatch stopwatch = Stopwatch.StartNew();
        //默认设置
        column.Sortable = true;
        column.Filterable = true;
        column.Width = "150";

        var getTmpProp = ModelPropertyTypeDic.GetValueOrDefault(propertyName);
        if (getTmpProp.Name.IsNullOrEmpty())
        {
            throw new ArgumentNullException($"DefinitionColumnsBase未找到属性{propertyName}");
        }

        var getType = getTmpProp.PropertyType;

        var underlyingType = getType.GetUnderlyingType();

        // 构造目标泛型类型
        Type tmpColtype = typeof(Column<>).MakeGenericType(underlyingType);

        var tmpColObj = column.ChangeType(tmpColtype);

        // 设置属性 Align
        ColumnSetValue(tmpColtype, tmpColObj, "Align", ColumnAlign.Center);

        // 设置属性 OnCell
        ColumnSetValue(tmpColtype, tmpColObj, "OnCell", OnCell);

        if (propertyName == "OrderNo")
        {
            column.Width = "80";
            var tmpValue = new[] { AntDesign.SortDirection.Descending, AntDesign.SortDirection.Ascending, AntDesign.SortDirection.Descending };
            // 设置属性 SortDirections
            ColumnSetValue(tmpColtype, tmpColObj, "SortDirections", tmpValue);
            ColumnSetValue(tmpColtype, tmpColObj, "DefaultSortOrder ", AntDesign.SortDirection.Descending);
        }

        if (ColumnsTitleDic.TryGetValue(propertyName, out string title))
        {
            // 设置属性 DisplayName
            ColumnSetValue(tmpColtype, tmpColObj, "DisplayName", title);
        }

        //其他特殊处理
        CellRenderByType(getType, tmpColtype, tmpColObj, propertyName, column, getTmpProp.isJsonColumn);

        CellEditRenderByType(getType, tmpColtype, tmpColObj, propertyName, column, getTmpProp.isJsonColumn);

        if (propertyName == "CreateUserName")
        {
            PropertyInfo CellRenderProp = tmpColtype.GetProperty("CellRender");

            RenderFragment<CellData<string>> tmpCellRender = cellData =>
             baseRender.GetPopoverCellRender(baseRender.GetDetails(cellData.RowData.GetRowData<ApplicationViewModel>()));

            CellRenderProp?.SetValue(tmpColObj, tmpCellRender);
        }
        stopwatch.Stop();
        if (stopwatch.ElapsedMilliseconds > 100)
        {
            Console.WriteLine($"{propertyName} DefinitionColumnsBase time:{stopwatch.ElapsedMilliseconds} ms");
        }
        return (getType, tmpColtype, tmpColObj);
    }
    /// <summary>
    /// Column 列 属性 设值
    /// </summary>
    /// <param name="tmpColtype"></param>
    /// <param name="tmpColInstance"></param>
    /// <param name="propertyName"></param>
    /// <param name="value"></param>
    private static void ColumnSetValue(Type tmpColtype, object tmpColInstance, string propertyName, object value)
    {
        PropertyInfo OnCellProp = tmpColtype.GetProperty(propertyName);
        OnCellProp?.SetValue(tmpColInstance, value);
    }

    private static void ColumnGetValue(object tmpColInstance, string propertyName, object value)
    {
        Type tmpColtype = tmpColInstance.GetType();
        PropertyInfo OnCellProp = tmpColtype.GetProperty(propertyName);
        OnCellProp?.GetValue(tmpColInstance);
    }

    public virtual Dictionary<string, TemplateConfigBase> GetDefaultColConfig()
    {
        var ShowColumnsByNamesLst = ColumnsByNamesShow.ToList();
        var tmpColConfig = ModelPropertyTypeDic.Keys
            .ToDictionary(k => k, k => new TemplateConfigBase() { Id = IdGenerator.NextId(), SortNo = ShowColumnsByNamesLst.IndexOf(k) + 1, OrderNo = ShowColumnsByNamesLst.IndexOf(k) + 1, KKey = k, Enable = ColumnsByNamesShow.Contains(k) });
        return tmpColConfig;
    }

    public virtual void DefinitionColumns(string propertyName, IFieldColumn column)
    {
        var getColDefine = DefinitionColumnsBase(propertyName, column);
        //to do
    }

    public virtual void ClickAction(string propertyName, IFieldColumn column)
    {
        selectedCol = propertyName;
        //to do
    }

    public virtual List<(string Name, Type PropertyType, string Parent)> ShowPropertyInfoAction(List<(string Name, Type PropertyType, string Parent)> propertyInfos)
    {
        var result = new List<(string Name, Type PropertyType, string Parent)>();

        foreach (var name in ColumnsByNamesShow)
        {
            var getP = propertyInfos.Where(a => a.Name == name).FirstOrDefault();
            if (getP.Name != null)
            {
                //是否有扩展
                if (TemplateKeyConsts.JsonDicColumn == getP.Name)
                {
                    foreach (var item in JsonColumnDic)
                    {
                        var tmpType = item.Value.Type.GetTypeByName();
                        result.Add(new(item.Key, tmpType, TemplateKeyConsts.JsonDicColumn));
                        ColumnsTitleDic.TryAdd(item.Key, item.Value.Name);
                        ModelPropertyTypeDic.TryAdd(item.Key, (item.Key, tmpType, null, true));
                    }
                }
                else
                {
                    result.Add(getP);
                }
            }
        }

        foreach (var item in JsonColumnDic.Keys)
        {
            if (ColumnsByNamesShow.Contains(item)) continue;
            ColumnsByNamesShow.Add(item);
        }

        return result;
        //to do
    }

    /// <summary>
    /// 获取标题
    /// </summary>
    /// <param name="propertyName"></param>
    /// <returns></returns>
    public virtual string GetTitle(string propertyName)
    {
        if (propertyName.IsNullOrEmpty())
        {
            return string.Empty;
        }
        if (ColumnsTitleDic.TryGetValue(propertyName, out var title))
        {
            return title;
        }
        return propertyName;
    }
    #region CellRender by type
    public virtual void CellEditRenderByType(Type getType, Type tmpColtype, object tmpCol, string propertyName, IFieldColumn column, bool isJsonColumn)
    {
        //不需要处理
        if (ColumnsByNamesNotCellRender.Contains(propertyName))
        {
            return;
        }

        //是否是扩展列 
        bool IsSelect = isJsonColumn && JsonColumnDic.TryGetValue(propertyName, out var properties) && properties != null && properties.IsSelect;

        switch (getType)
        {
            case var i when i.IsEnum():
                CellRenderInvokeGenericMethod(getType, tmpColtype, tmpCol, propertyName, "GetEnumCellRenderRenderFragment", true);
                break;
            case var i when i.IsString():
                if (IsSelect)
                {

                    CellRenderSetValue<string>(tmpColtype, tmpCol, propertyName, GetSelectCellRender<string, string>);
                }
                else
                {
                    CellRenderSetValue<string>(tmpColtype, tmpCol, propertyName, GetInputTTCellRender);
                }
                break;
            case var i when i.IsBool():
                CellRenderSetValue<bool>(tmpColtype, tmpCol, propertyName, GetSwitchCellRender);
                break;
            case var i when i.IsNumericType():
                CellRenderInvokeGenericMethod(getType, tmpColtype, tmpCol, propertyName, "GetInputNumberTTCellRenderFragment", true);
                break;
            case var i when i.IsDateType():
                CellRenderInvokeGenericMethod(getType, tmpColtype, tmpCol, propertyName, "GetTimePickerTTCellRenderFragment", true);
                break;
            default:
                CheckOtherBaseType(getType, tmpColtype, tmpCol, propertyName, column);
                break;
        }
        ;
    }

    /// <summary>
    /// 处理基础类型，如枚举等
    /// </summary>
    /// <param name="getType"></param>
    /// <param name="tmpColtype"></param>
    /// <param name="tmpCol"></param>
    /// <param name="propertyName"></param>
    /// <param name="column"></param>
    public virtual void CheckOtherBaseType(Type getType, Type tmpColtype, object tmpCol, string propertyName, IFieldColumn column, bool isEdit = true)
    {
        var baseType = getType.BaseType;
        if (baseType != null)
        {
            var baseFullName = baseType.FullName;
            switch (baseFullName)
            {
                case string i when i.Contains(TypeConsts.enum12):

                    CellRenderInvokeGenericMethod(getType, tmpColtype, tmpCol, propertyName, "GetEnumCellRenderRenderFragment", isEdit);
                    break;
                default:
                    Console.WriteLine($"CheckBaseType当前类型[{baseFullName}]不支持");
                    break;
            }
        }
    }
    #region CellRenderInvokeGenericMethod
    private void CellRenderInvokeGenericMethod(Type getType, Type tmpColtype, object tmpCol, string propertyName, string genericMethod, bool isEdit)
    {
        object result = InvokeGenericMethod(Me, getType, genericMethod, propertyName, isEdit);
        string cellRenderName = isEdit ? "CellEditRender" : "CellRender";

        PropertyInfo CellRenderProp = tmpColtype.GetProperty(cellRenderName);

        CellRenderProp?.SetValue(tmpCol, result);
    }
    public virtual RenderFragment<CellData<TT>> GetTextTTCellRenderFragment<TT>(string propertyName, bool isEdit = true)
    {
        // 假设已有以下变量
        Func<CellData<TT>, string, RenderFragment> func = GetTextCellRender<TT>;

        RenderFragment<CellData<TT>> tmpCellRender = cellData =>
        {
            if (!isEdit && ColumnsByNamesPropertySet.TryGetValue(propertyName, out Dictionary<string, object> configset))
            {
                cellData.Prop = configset;
            }
            return func.Invoke(cellData, propertyName);
        };

        return tmpCellRender;
    }
    public virtual RenderFragment<CellData<TT>> GetInputTTCellRenderFragment<TT>(string propertyName, bool isEdit = true)
    {
        // 假设已有以下变量
        Func<CellData<TT>, string, RenderFragment> func = GetInputTTCellRender<TT>;

        RenderFragment<CellData<TT>> tmpCellRender = cellData =>
        {
            if (!isEdit && ColumnsByNamesPropertySet.TryGetValue(propertyName, out Dictionary<string, object> configset))
            {
                cellData.Prop = configset;
            }
            return func.Invoke(cellData, propertyName);
        };

        return tmpCellRender;
    }
    public virtual RenderFragment<CellData<TT>> GetTimePickerTTCellRenderFragment<TT>(string propertyName, bool isEdit = true)
    {
        // 假设已有以下变量
        Func<CellData<TT>, string, RenderFragment> func = GetTimePickerTTCellRender<TT>;

        RenderFragment<CellData<TT>> tmpCellRender = cellData =>
        {
            if (!isEdit && ColumnsByNamesPropertySet.TryGetValue(propertyName, out Dictionary<string, object> configset))
            {
                cellData.Prop = configset;
            }
            return func.Invoke(cellData, propertyName);
        };

        return tmpCellRender;
    }
    public virtual RenderFragment<CellData<TT>> GetInputNumberTTCellRenderFragment<TT>(string propertyName, bool isEdit = true)
    {
        // 假设已有以下变量
        Func<CellData<TT>, string, RenderFragment> func = GetInputNumberTTCellRender<TT>;

        RenderFragment<CellData<TT>> tmpCellRender = cellData =>
        {
            if (!isEdit && ColumnsByNamesPropertySet.TryGetValue(propertyName, out Dictionary<string, object> configset))
            {
                cellData.Prop = configset;
            }
            return func.Invoke(cellData, propertyName);
        };

        return tmpCellRender;
    }
    public virtual RenderFragment<CellData<TT>> GetEnumCellRenderRenderFragment<TT>(string propertyName, bool isEdit = true)
      where TT : Enum
    {
        // 假设已有以下变量
        Func<CellData<TT>, string, RenderFragment> func = GetEnumCellRender<TT>;

        RenderFragment<CellData<TT>> tmpCellRender = cellData =>
        {
            if (!isEdit && ColumnsByNamesPropertySet.TryGetValue(propertyName, out Dictionary<string, object> configset))
            {
                cellData.Prop = configset;
            }
            return func.Invoke(cellData, propertyName);
        };

        return tmpCellRender;
    }

    #endregion

    public virtual void CellRenderByType(Type getType, Type tmpColtype, object tmpCol, string propertyName, IFieldColumn column, bool isJsonColumn)
    {
        //不需要处理
        if (ColumnsByNamesNotCellRender.Contains(propertyName))
        {
            return;
        }

        //是否是扩展列 
        bool IsSelect = isJsonColumn && JsonColumnDic.TryGetValue(propertyName, out var properties) && properties != null && properties.IsSelect;

        switch (getType)
        {
            case var i when i.IsString():
                if (IsSelect)
                {
                    CellRenderInvokeGenericMethod(getType, tmpColtype, tmpCol, propertyName, "GetTextTTCellRenderFragment", false);
                }
                break;
            case var i when i.IsBool():
                CellRenderSetValue<bool>(tmpColtype, tmpCol, propertyName, GetSwitchCellRender, false);
                break;

            case var i when i.IsDateType():
                CellRenderInvokeGenericMethod(getType, tmpColtype, tmpCol, propertyName, "GetTextTTCellRenderFragment", false);
                break;

            default:
                //Console.WriteLine($"CellRenderByType 当前类型[{getType.FullName}]不支持"); //不支持的类型,使用默认的
                break;
        }
        ;
    }

    public void CellRenderSetValue<TT>(Type tmpColtype, object tmpCol, string propertyName, Func<CellData<TT>, string, RenderFragment> func, bool isEdit = true)
    {
        // 设置属性 FilterDropdown
        //PropertyInfo FilterDropdownProp = tmpColtype.GetProperty("FilterDropdown");
        //FilterDropdownProp?.SetValue(tmpCol, baseRender.ShowHeader(propertyName)); 

        string cellRenderName = isEdit ? "CellEditRender" : "CellRender";

        PropertyInfo CellRenderProp = tmpColtype.GetProperty(cellRenderName);
        RenderFragment<CellData<TT>> tmpCellRender = cellData =>
        {
            if (!isEdit && ColumnsByNamesPropertySet.TryGetValue(propertyName, out Dictionary<string, object> configset))
            {
                cellData.Prop = configset;
            }
            return func.Invoke(cellData, propertyName);
        };

        CellRenderProp?.SetValue(tmpCol, tmpCellRender);
    }

    public virtual void CellDataInitProp<TT>(CellData<TT> cellData)
    {
        if (cellData == null) throw new ArgumentNullException("CellData参数为null");
        if (cellData.Prop == null)
        {
            cellData.Prop = new Dictionary<string, object>();
        }
    }
    #endregion
    #region CellRender
    /// <summary>
    /// 状态相关
    /// </summary>
    /// <param name="cellData"></param>
    /// <param name="action"></param>
    /// <returns></returns>
    // 动态构建一个包含按钮的 RenderFragment
    public virtual RenderFragment GetSwitchCellRender(CellData<bool> cellData, string filedName) => builder =>
    {
        var action = () =>
        {
            EditModelValue(cellData, filedName);
        };

        var divClickaction = () =>
        {
            selectedCol = filedName;
        };

        int i = 0;
        builder.OpenElement(i++, "div");
        builder.AddAttribute(i++, "class", "fill-section");
        builder.AddAttribute(i++, "onclick", EventCallback.Factory.Create(this, divClickaction));

        builder.OpenComponent<AntDesign.Switch>(i++);
        builder.AddAttribute(i++, "value", cellData.FieldValue);
        // 添加值改变事件回调
        builder.AddAttribute(i++, "ValueChanged",
            EventCallback.Factory.Create<bool>(
                this,
                __value =>
                {
                    cellData.FieldValue = __value; // 当值改变时，更新数据源
                                                   // 可选: 如果需要，可以在这里调用 StateHasChanged 或其他逻辑
                    EditModelValue(cellData, filedName);
                }
            ));
        // 使用 EventCallback.Factory.Create 来分配事件
        //builder.AddAttribute(i++, "OnClick", EventCallback.Factory.Create(this, action));
        builder.AddAttribute(i++, "CheckedChildren", "开");
        builder.AddAttribute(i++, "UnCheckedChildren", "关");

        if (cellData.Prop != null && cellData.Prop.TryGetValue("Disabled", out object Disabled))
        {
            builder.AddAttribute(i++, "Disabled", Disabled);
        }
        ;

        builder.CloseComponent(); // 关闭组件

        builder.CloseElement(); // 关闭组件
    };

    public virtual Func<TT, string, string> GetFormatToStringFunc<TT>() => (value, format) =>
    {
        if (format.IsNullOrEmpty())
        {
            return value?.ToString();
        }
        var getMethod = typeof(TT).GetMethod("ToString", new Type[] { typeof(string) });
        if (getMethod != null)
        {
            return getMethod.Invoke(value, new object[] { format })?.ToString();
        }

        return value?.ToString();
    };
    public virtual RenderFragment GetTextCellRender<TT>(CellData<TT> cellData, string filedName)
    {
        JsonColumnDic.TryGetValue(filedName, out var properties);
        var IsSelect = properties?.IsSelect ?? false;
        var isMultiLine = properties?.Multiple ?? false;
        string format = properties?.Format ?? "";

        var getType = typeof(TT);

        string formatValue = string.Empty;
        if (IsSelect)
        {
            //是否是扩展下拉
            Dictionary<TT, string> _dict = GetJsonColumnOptionsDic<TT, string>(filedName);

            if (_dict != null && _dict.TryGetValue(cellData.FieldValue, out string tmpStr))
            {
                formatValue = tmpStr;
            }
        }
        else if (!format.IsNullOrEmpty() && (getType.IsDateType() || getType.IsNumericType()))
        {
            Func<TT, string, string> formatDateFunc = GetFormatToStringFunc<TT>();
            formatValue = formatDateFunc(cellData.FieldValue, format);
        }
        else
        {
            formatValue = cellData.FieldValue?.ToString();
        }
        return baseRender.GetTextCellRender(cellData, filedName, formatValue);
    }
    public virtual RenderFragment GetInputTTCellRender<TT>(CellData<TT> cellData, string filedName) => builder =>
    {
        //var action = () =>
        //{
        //    EditModelValue(cellData, filedName);
        //};
        //var divClickaction = () =>
        //{
        //    selectedCol = filedName;
        //}; 


        Func<TT, string, string> formatDateFunc = GetFormatToStringFunc<TT>();
        bool IsToolTip = false;
        string toolTip = string.Empty;

        //是否显示ToolTip
        if (cellData.Prop != null && cellData.Prop.TryGetValue("IsToolTip", out bool tmpToolTip))
        {
            IsToolTip = tmpToolTip;
            Dictionary<TT, string> _dict = GetJsonColumnOptionsDic<TT, string>(filedName);

            if (_dict != null && _dict.TryGetValue(cellData.FieldValue, out string tmpToolTipStr))
            {
                toolTip = tmpToolTipStr;
            }
            else
            {
                toolTip = cellData.FieldValue?.ToString();
            }

            IsToolTip = !toolTip.IsNullOrEmpty();
        }

        int i = 0;

        Action<RenderTreeBuilder> action = builder2 =>
        {
            JsonColumnDic.TryGetValue(filedName, out var properties);
            var isMultiLine = properties?.Multiple ?? false;
            string format = properties?.Format ?? "";

            if (isMultiLine)
            {
                builder2.OpenComponent<TextArea>(i++);
                builder2.AddAttribute(i++, "value", cellData.FieldValue);

                uint row = properties.Options.Data.TryGetValue("Rows", out var r) ? r.ToUInt(1) : 3;

                builder2.AddAttribute(i++, "Rows", row);

            }
            else
            {
                builder2.OpenComponent<Input<TT>>(i++);

                if (!format.IsNullOrEmpty() && typeof(TT).IsDateType())
                {
                    builder2.AddAttribute(i++, "Format", format);
                    builder2.AddAttribute(i++, "FormatFunc", formatDateFunc);
                }
            }

            builder2.AddAttribute(i++, "value", cellData.FieldValue);
            // 添加值改变事件回调
            builder2.AddAttribute(i++, "ValueChanged",
                EventCallback.Factory.Create<TT>(
                    this,
                    __value =>
                    {
                        cellData.FieldValue = __value; // 当值改变时，更新数据源
                                                       // 可选: 如果需要，可以在这里调用 StateHasChanged 或其他逻辑
                        EditModelValue(cellData, filedName);
                    }
                ));
            // 使用 EventCallback.Factory.Create 来分配事件
            //builder2.AddAttribute(i++, "OnClick", EventCallback.Factory.Create(this, action));
            builder2.CloseComponent(); // 关闭组件
        };

        if (IsToolTip)
        {
            builder.OpenComponent<AntDesign.Tooltip>(i++);
            builder.AddAttribute(i++, "Title", toolTip);
            builder.AddAttribute(i++, "Placement", Placement.Right);
            builder.AddAttribute(i++, "ChildContent", (RenderFragment)((builder2) =>
            {
                action(builder2);
            }));
            builder.CloseComponent(); // 关闭组件 
        }
        else
        {
            action(builder);
        }

    };
    public virtual RenderFragment GetEnumCellRender<TT>(CellData<TT> cellData, string filedName)
        where TT : Enum => builder =>
    {
        //var action = () =>
        //{
        //    EditModelValue(cellData, filedName);
        //};
        //var divClickaction = () =>
        //{
        //    selectedCol = filedName;
        //};

        int i = 0;
        builder.OpenComponent<EnumSelect<TT>>(i++);
        builder.AddAttribute(i++, "value", cellData.FieldValue);
        // 添加值改变事件回调
        builder.AddAttribute(i++, "ValueChanged",
            EventCallback.Factory.Create<TT>(
                this,
                __value =>
                {
                    cellData.FieldValue = __value; // 当值改变时，更新数据源
                                                   // 可选: 如果需要，可以在这里调用 StateHasChanged 或其他逻辑
                    EditModelValue(cellData, filedName);
                }
            ));
        // 使用 EventCallback.Factory.Create 来分配事件
        //builder.AddAttribute(i++, "OnClick", EventCallback.Factory.Create(this, action));
        builder.CloseComponent(); // 关闭组件 
    };

    public Dictionary<TT, TTValue> GetJsonColumnOptionsDic<TT, TTValue>(string filedName, bool isMergeKV = true)
    {
        var _dict = new Dictionary<TT, TTValue>();

        //是否是扩展列
        if (!JsonColumnDic.TryGetValue(filedName, out var properties) || !properties.IsSelect || properties.Options.Data == null)
        {
            return _dict;
        }
        switch (properties.Options.Type)
        {
            case "dictionary":
                _dict = (properties.Options.Data as Dictionary<TT, TTValue>);
                if (isMergeKV)
                {
                    _dict = _dict?.MergeKVCopy();
                }
                break;
            default:
                break;
        }

        return _dict;
    }

    public virtual RenderFragment GetSelectCellRender<TT, TTValue>(CellData<TT> cellData, string filedName)
        where TT : notnull
     => builder =>
    {
        //var action = () =>
        //{
        //    EditModelValue(cellData, filedName);
        //};
        //var divClickaction = () =>
        //{
        //    selectedCol = filedName;
        //};

        //是否是扩展列 
        Dictionary<TT, TTValue> _dict = GetJsonColumnOptionsDic<TT, TTValue>(filedName);
        if (_dict == null || _dict.Count <= 0)
        {
            GetInputTTCellRender<TT>(cellData, filedName);
            return;
        }

        //Dictionary<string, string> _dict = new Dictionary<string, string>() {
        //    { "aa", "测试aa" },
        //    { "bb", "测试bb" },
        //    { "cc", "测试cc" },
        //};

        int i = 0;
        builder.OpenComponent<Select<TT, KeyValuePair<TT, TTValue>>>(i++);

        Func<KeyValuePair<TT, TTValue>, TT> _funcKey = a => a.Key;
        Func<KeyValuePair<TT, TTValue>, TTValue> _funcValue = a => a.Value;

        builder.AddAttribute(i++, "DataSource", _dict);
        builder.AddAttribute(i++, "ItemLabel", _funcValue);
        builder.AddAttribute(i++, "ItemValue", _funcKey);
        builder.AddAttribute(i++, "EnableSearch", true);

        builder.AddAttribute(i++, "value", cellData.FieldValue);
        // 添加值改变事件回调
        builder.AddAttribute(i++, "ValueChanged",
                EventCallback.Factory.Create<TT>(
                    this,
                    __value =>
            {
                cellData.FieldValue = __value; // 当值改变时，更新数据源
                                               // 可选: 如果需要，可以在这里调用 StateHasChanged 或其他逻辑
                EditModelValue(cellData, filedName);
            }
                ));
        // 使用 EventCallback.Factory.Create 来分配事件
        //builder.AddAttribute(i++, "OnClick", EventCallback.Factory.Create(this, action));

        if (cellData.Prop != null && cellData.Prop.TryGetValue("Disabled", out object Disabled))
        {
            builder.AddAttribute(i++, "Disabled", Disabled);
        }
        ;

        builder.CloseComponent(); // 关闭组件 
    };

    public virtual RenderFragment GetInputNumberTTCellRender<TT>(CellData<TT> cellData, string filedName) => builder =>
    {
        //var action = () =>
        //{
        //    EditModelValue(cellData, filedName);
        //};
        //var divClickaction = () =>
        //{
        //    selectedCol = filedName;
        //};

        int i = 0;
        builder.OpenComponent<InputNumber<TT>>(i++);
        builder.AddAttribute(i++, "value", cellData.FieldValue);
        // 添加值改变事件回调
        builder.AddAttribute(i++, "ValueChanged",
            EventCallback.Factory.Create<TT>(
                this,
                __value =>
                {
                    cellData.FieldValue = __value; // 当值改变时，更新数据源
                                                   // 可选: 如果需要，可以在这里调用 StateHasChanged 或其他逻辑
                    EditModelValue(cellData, filedName);
                }
            ));
        // 使用 EventCallback.Factory.Create 来分配事件
        //builder.AddAttribute(i++, "OnClick", EventCallback.Factory.Create(this, action));
        builder.CloseComponent(); // 关闭组件 
    };

    public virtual RenderFragment GetTimePickerTTCellRender<TT>(CellData<TT> cellData, string filedName) => builder =>
    {
        //var action = () =>
        //{
        //    EditModelValue(cellData, filedName);
        //};
        //var divClickaction = () =>
        //{
        //    selectedCol = filedName;
        //};

        int i = 0;
        if (typeof(TT) == TypeConsts.TimeOnly)
        {
            builder.OpenComponent<TimePicker<TT>>(i++);
        }
        else
        {
            builder.OpenComponent<DatePicker<TT>>(i++);
        }
        builder.AddAttribute(i++, "value", cellData.FieldValue);
        // 添加值改变事件回调
        builder.AddAttribute(i++, "ValueChanged",
            EventCallback.Factory.Create<TT>(
                this,
                __value =>
                {
                    cellData.FieldValue = __value; // 当值改变时，更新数据源
                                                   // 可选: 如果需要，可以在这里调用 StateHasChanged 或其他逻辑
                    EditModelValue(cellData, filedName);
                }
            ));
        // 使用 EventCallback.Factory.Create 来分配事件
        //builder.AddAttribute(i++, "OnClick", EventCallback.Factory.Create(this, action));
        builder.CloseComponent(); // 关闭组件 
    };

    /// <summary>
    /// 根据字段名进行状态切换
    /// </summary>
    /// <param name="t"></param>
    /// <param name="filedName"></param>
    /// <exception cref="NotImplementedException"></exception>
    public virtual Task EditModelValue<TT>(CellData<TT> cellData, string filedName)
    {

        selectedCol = filedName;
        var getType = ModelPropertyTypeDic[filedName];
        var t = cellData.RowData.GetRowData<T>();

        if (getType.PropertyInfo == null && cellData.Name.StartsWith(TemplateKeyConsts.JsonDicColumn))
        {
            //扩展列 
            var getJsonPropertyInfo = ModelPropertyTypeDic[TemplateKeyConsts.JsonDicColumn].PropertyInfo;
            var getValue = getJsonPropertyInfo.GetValue(t);
            if (getValue is Dictionary<string, JsonColumnPropertiesBase> tmpDic)
            {
                tmpDic[filedName].Value = cellData.FieldValue;
                getJsonPropertyInfo.SetValue(t, tmpDic);
            }
        }
        else
        {
            // 设置属性 
            getType.PropertyInfo?.SetValue(t, cellData.FieldValue);
        }

        OnModelChangedAction(t, ChangedEnum.Modified);
        return Task.CompletedTask;
    }


    #endregion
    #region cell click
    public virtual Dictionary<string, object> OnCell(CellData cellData) => new()
    {
        ["onclick"] = () =>
        {
            selectedCol = cellData.Name;

            CheckSelectedRowEditing(((RowData<T>)cellData.RowData));

            //Console.WriteLine($"cell {selectedRow.Id} was clicked");
        }
    };

    public virtual Dictionary<string, object> OnHeaderCell() => new()
    {
        ["onclick"] = () =>
        {
            Console.WriteLine("header cell was clicked");
        }
    };
    #endregion
    #region row
    public virtual async Task UpRow(T d)
    {

        if (d is ISort dd && dd.OrderNo > 1)
        {
            var getData = pageData.Items.ToList();
            var updateSourtNo = getData.Where(a => a is ISort aa && aa.OrderNo == (dd.OrderNo - 1)).FirstOrDefault();
            if (updateSourtNo != null)
            {
                ((ISort)updateSourtNo).OrderNo++;
                await table.ScrollItemIntoView(updateSourtNo);
            }
            dd.OrderNo--;
            pageData.Items = getData.OrderBy(a => ((ISort)a).OrderNo);
            selectedRows = new List<T>() { d };
            table.ReloadData();
        }

    }
    public virtual async Task DownRow(T d)
    {
        var getData = pageData.Items.ToList();
        if (d is ISort dd && dd.OrderNo < getData.Count)
        {
            var updateSourtNo = getData.Where(a => a is ISort aa && aa.OrderNo == (dd.OrderNo + 1)).FirstOrDefault();
            if (updateSourtNo != null)
            {
                ((ISort)updateSourtNo).OrderNo--;
                await table.ScrollItemIntoView(updateSourtNo);
            }
            dd.OrderNo++;
            pageData.Items = getData.OrderBy(a => ((ISort)a).OrderNo);
            selectedRows = new List<T>() { d };
            table.ReloadData();
        }

    }
    #endregion
    #endregion
}
